package domain

import (
	"gluenet/modules/manager/server/domain/aggregate"
	"gluenet/modules/manager/server/domain/dependency"
	"gluenet/modules/manager/server/domain/entity"
	"gluenet/modules/manager/server/domain/vo"
	"gluenet/modules/manager/server/infra/prepare"
)

func init() {
	//fmt.Printf("domina init\n")
	prepare.RegisterService(func() {
		config := NewConfigDomain()
		prepare.InjectDependency(func() *Config {
			return config
		})
	})
}

type Config struct {
	ConfigRepo    dependency.ConfigMetaRepo
	DetailRepo    dependency.DetailRepo
	TagRepo       dependency.TagRepo
	UserRepo      dependency.UserRepo
	CreateFactroy *aggregate.ConfigCreateFactory
}

func NewConfigDomain() *Config {
	domain := &Config{}
	prepare.FetchDependency(&domain.CreateFactroy)
	prepare.FetchDependency(&domain.DetailRepo)
	prepare.FetchDependency(&domain.ConfigRepo)
	prepare.FetchDependency(&domain.UserRepo)
	//prepare.FetchDependency(&domain.TagRepo)
	return domain
}

func (r *Config) Create(req vo.CreateConfigReq) (interface{}, error) {
	cfg, err := r.CreateFactroy.CreateConfig(req)
	if err != nil {
		return nil, err
	}
	cfgRes := cfg.ShowInfo()
	return cfgRes, nil
}

//func (r *Config) Update(req vo.UpdateConfigReq) (*entity.Config, error) {
//	obj, err := r.ConfigRepo.Get(req.ConfigID, req.UserID)
//	if err != nil {
//		return nil, err
//	}
//	if err = obj.Update(&req); err != nil {
//		return nil, err
//	}
//	if err = r.ConfigRepo.Update(obj); err != nil {
//		return nil, err
//	}
//	return obj, nil
//}

func (r *Config) Delete(admin bool, userId, config string) (*entity.Config, error) {
	obj, err := r.ConfigRepo.Del(admin, userId, config)
	if err != nil {
		return nil, err
	}
	return obj, nil
}

//func (r *Config) Get(id string) (*entity.Config, error) {
//	obj, err := r.ConfigRepo.Get(id)
//	if err != nil {
//		return nil, err
//	}
//	return obj, nil
//}

//func (r *Config) MarkedTag(id string, key, value string) error {
//	return r.TagRepo.New(id, key, value)
//}

//func (r *Config) FindAll() ([]entity.Config, error) {
//	return r.ConfigRepo.FindAll()
//}

func (r *Config) FindByUser(user string, admin bool, query map[string]interface{}) ([]interface{}, error) {
	var (
		err  error
		cfgs []entity.Config
	)
	if !admin {
		query["user_id"] = user
	}

	cfgs, err = r.ConfigRepo.FindBy(query)
	if err != nil {
		return nil, err
	}
	var cfgRes = make([]interface{}, len(cfgs))
	for index, cfg := range cfgs {
		cfg.DetailRepoValue, err = r.DetailRepo.GetByRepoKey(cfg.DetailRepoKey)
		if err != nil {
			return nil, err
		}
		cfgRes[index] = cfg.ShowInfo()
	}
	return cfgRes, nil
}

//func (r *Config) FindByTag(kvs map[string]string, userID string) ([]*entity.Config, error) {
//	ids, err := r.TagRepo.FindObjects(kvs)
//	if err != nil {
//		return nil, err
//	}
//	var config = make([]*entity.Config, len(ids))
//	for i, id := range ids {
//		cfg, err := r.ConfigRepo.Get(id, userID)
//		if err != nil {
//			return nil, err
//		}
//		config[i] = cfg
//	}
//	return config, err
//}
